package com.yds.socket.server;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;

import com.yds.socket.CodeType;
import com.yds.socket.bean.OtherMsgBean;
import com.yds.socket.utils.SocketBytesUtil;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 作者:     YDS
 * 创建时间: 2023/2/14 13:03
 * 页面描述: Socket服务端
 */
public class SocketServer implements LifecycleObserver {

    private Timer timer;
    private TimerTask timerTask;

    private ServerSocket serverSocket = null;
    private Socket socket = null;
    private ServerCallback callback;
    private ExecutorService threadPool;
    private OutputStream outputStream;
    // 接收客服端消息线程
    private ServerThread serverThread;
    // 已连接客户端socket集合
    private List<Socket> mSocketList;

    private boolean isRunning = true;

    /**
     * 开启socket服务端
     *
     * @param socketPort 服务端端口
     * @param callback   服务端信息回调
     */
    public void startSocketServer(int socketPort, @NonNull ServerCallback callback) {
        this.callback = callback;

        if (null != serverSocket && !serverSocket.isClosed()) {
            callback.otherMsg(new OtherMsgBean(CodeType.ERROR_MSG, "socket服务端正在运行，请勿重复开启"));
        } else {
            // 重置已保存的Socket客户端集合
            mSocketList = new ArrayList<>();
            // 开启Timer，轮训判断客户端状态
            timer = new Timer();
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    for (Socket socket : mSocketList) {
                        // 测试客户端是否断开连接
                        try {
                            if (null != socket) {
                                socket.sendUrgentData(1);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            callback.otherMsg(new OtherMsgBean(CodeType.DISCONNECT_SOCKET, socket));
                            mSocketList.remove(socket);
                        }
                    }
                }
            };
            timer.schedule(timerTask, 1000, 2000);

            if (null == threadPool || threadPool.isShutdown()) {
                // 初始化缓存线程池
                threadPool = Executors.newCachedThreadPool();
            }
            threadPool.submit(() -> {
                try {
                    isRunning = true;
                    InetSocketAddress inetSocketAddress = new InetSocketAddress(socketPort);
                    serverSocket = new ServerSocket();
                    serverSocket.setReuseAddress(true);
                    serverSocket.bind(inetSocketAddress);
//                    callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "Socket服务端已开启: "+serverSocket.getInetAddress()));
                    // 替换为：
                    String localIp = getLocalIpAddress(); // 获取本地IP
                    int port = serverSocket.getLocalPort(); // 获取服务端端口
                    callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "Socket服务端已开启: IP=" + localIp + ", 端口=" + port));

                    // 循环接收连接请求
                    while (isRunning) {
                        if (!serverSocket.isClosed()) {
                            // 如果未连接会阻塞直到有客户端连接
                            socket = serverSocket.accept();
                        }
                        mSocketList.add(socket);
                        serverThread = new ServerThread(socket, callback);
                        serverThread.start();
                        callback.otherMsg(new OtherMsgBean(CodeType.CONNECT_SOCKET, socket));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    if (isRunning) {
                        isRunning = false;
                        callback.otherMsg(new OtherMsgBean(CodeType.EXCEPTION_MSG, "开启socket服务端 IOException: " + e.getMessage()));
                    }
                }
            });
        }
    }

    // 新增：获取本地IP地址（非回环、IPv4）
    public static String getLocalIpAddress() {
        try {
            // 遍历所有网络接口
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface networkInterface = interfaces.nextElement();
                // 过滤掉虚拟接口和未启用的接口
                if (networkInterface.isLoopback() || !networkInterface.isUp()) {
                    continue;
                }
                // 遍历接口下的所有IP地址
                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress address = addresses.nextElement();
                    // 只返回IPv4地址（非回环）
                    if (address instanceof Inet4Address && !address.isLoopbackAddress()) {
                        return address.getHostAddress(); // 返回IP地址（如192.168.113.49）
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        // 如果没有找到有效IP，返回本地回环地址（仅作为默认值）
        return "127.0.0.1";
    }

    /**
     * 关闭socket服务端
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void stopSocketServer() {
        isRunning = false;

        if (null != timer) {
            timer.cancel();
            timer = null;
            if (null != callback) {
                callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "关闭socket服务端 timer.cancel()"));
            }
        }

        if (null != timerTask) {
            timerTask.cancel();
            timerTask = null;
            if (null != callback) {
                callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "关闭socket服务端 timerTask.cancel()"));
            }
        }

        if (null != serverThread) {
            serverThread.interrupt();
            if (null != callback) {
                callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "关闭socket服务端 serverThread.interrupt()"));
            }
        }

        if (null != threadPool) {
            threadPool.shutdownNow();
            if (null != callback) {
                callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "关闭socket服务端 threadPool.shutdownNow()"));
            }
        }

        if (null != socket) {
            try {
                socket.shutdownInput();
                socket.shutdownOutput();
                socket.close();
                if (null != callback) {
                    callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "关闭socket服务端 socket.close()"));
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (null != callback) {
                    callback.otherMsg(new OtherMsgBean(CodeType.EXCEPTION_MSG, "关闭socket服务端 Exception: " + e.getMessage()));
                }
            }
        }

        if (null != serverSocket) {
            try {
                serverSocket.close();
                if (null != callback) {
                    callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "关闭socket服务端 serverSocket.close()"));
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (null != callback) {
                    callback.otherMsg(new OtherMsgBean(CodeType.EXCEPTION_MSG, "关闭socket服务端 Exception: " + e.getMessage()));
                }
            }
        }
    }

    /**
     * 向客户端发送消息
     *
     * @param msg 消息内容
     */
    public void sendMsgToClient(String msg) {
        if (null == threadPool || threadPool.isShutdown()) {
            if (null != callback) {
                callback.otherMsg(new OtherMsgBean(CodeType.ERROR_MSG, "向服务端发送消息失败: threadPool = null | threadPool.isShutdown()"));
            }
        } else {
            threadPool.submit(() -> {
                if (null != socket) {
                    if (!socket.isClosed()) {
                        try {
                            outputStream = socket.getOutputStream();
                            outputStream.write(SocketBytesUtil.convertStringToBytes(msg));
                            outputStream.flush();
                            callback.otherMsg(new OtherMsgBean(CodeType.SUCCESS_MSG, "发送到客户端成功: " + msg));
                        } catch (IOException e) {
                            e.printStackTrace();
                            if (null != callback) {
                                callback.otherMsg(new OtherMsgBean(CodeType.EXCEPTION_MSG, "向客户端发送消息失败: " + e.getMessage()));
                            }
                        }
                    } else {
                        if (null != callback) {
                            callback.otherMsg(new OtherMsgBean(CodeType.ERROR_MSG, "向客户端发送消息失败: socket.isClosed()"));
                        }
                    }
                } else {
                    if (null != callback) {
                        callback.otherMsg(new OtherMsgBean(CodeType.ERROR_MSG, "向客户端发送消息失败，暂无客户端连接: socket = null"));
                    }
                }
            });
        }
    }

}
